/*
 * IcmpErrorSession.cpp
 *
 *  Created on: 27/08/2011
 *      Author: george
 */

#include "icmperrorsession.h"

//bibliotecas de rede
#include <netinet/in.h>
#include <arpa/inet.h>

//saida e entrada (fluxos de arquivo)
#include <sstream>
#include <iostream>
#include <string>

//bibliotecas padrao do c
#include <cstdlib>
#include <sys/time.h>

#include "info.h"

using namespace std;

IcmpErrorSession::IcmpErrorSession(struct in_addr src, struct in_addr dst){
	this->src = src;
	this->dst = dst;

	Info::getInstance()->nmIcmpErrorSessions++;

	timeval tval;

//	Nome legivel da origem e destino da sessao icmp
	this->srcaddr = inet_ntoa(this->src);
	this->dstaddr = inet_ntoa(this->dst);

	//	Nome unico para o arquivo
	stringstream timestam_name;

//	Para gerar o identificador como nome
//	Sessões icmp de erro nao possuem um campo id, mas iremos utilizar o tempo para diferenciar arquivos
	gettimeofday(&tval, 0);
	timestam_name << tval.tv_usec;

	stringstream idnome;


//  Determina o nome do arquivo que deve armazenar os pacotes
	idnome << hex << tval.tv_usec;

	this->filename = "icmp-error-" + idnome.str() + "-" + this->srcaddr  + "-" + this->dstaddr + "-" + timestam_name.str() + ".xml";

	this->packets.open(this->filename.c_str(), ofstream::app | fstream::ate);

	if ( !this->packets.is_open()){
		cout << "Erro ao abrir o arquivo " << this->filename << endl;

	}

	this->packets << "<icmperrorsession src='" + this->srcaddr + "' dst='" + this->dstaddr + "' id='" + idnome.str() + "' >" << endl;
}

bool IcmpErrorSession::add(icmp_hdr_t *p){

//	Verifica se o arquivo de saida esta aberto ou nao, se nao estiver o abre

	if (!this->packets.is_open()){
		this->packets.open(this->filename.c_str(), ofstream::app | ofstream::ate);

		if ( !this->packets.is_open() ){
			cout << "O arquivo " << this->filename << " não pode ser aberto" << endl;
			return false;
		}
	}

//	Ajusta o curso dentro do texto para sobrescrever o fim da tag icmpsession, desta forma sempre colocamops os pacotes detro do <icmpsession></icmpsession>
//	int end = this->packets.tellp();
//	this->packets.seekp(end - 19);

//	Escreve os dados do pacote capturado


//	Formato para Echo, Echo Reply, Information Request, Information Reply Message
	this->packets << "<icmp type='" 	<<
	   (int)(p->type) << "' code='"	    <<
	   (int)(p->code) << "' checksum='" << hex << showbase << p->checksum <<  "' />";

	this->packets <<  "</icmpsession>" << endl;

	this->packets.flush();
	this->packets.close();
	return true;
}

IcmpErrorSession::~IcmpErrorSession() {

	if ( this->packets.is_open()){
		this->packets.flush();
		this->packets.close();
	}
	// TODO Auto-generated destructor stub
}
